import * as d3 from 'd3';
import * as topojson from 'topojson-client';
import * as projTools from "@/utils/projection/projectionTools.js";
import {h} from "vue";


function clearCanvas(ctx, width, height) {
    ctx.clearRect(0, 0, width, height);
}

let _data = [];

function renderCanvas(d, path, ctx, renderer = false) {
    if (!renderer) {
        _data.push(d);
    }
    ctx.beginPath();
    path(d);
    let props = d.props || d.properties;
    if (props && props.fill) {
        ctx.fillStyle = props.fill;
        ctx.fill();
    }
    ctx.strokeStyle = props ? props.stroke || 'black' : 'black';
    ctx.lineWidth = props ? props['stroke-width'] || props['line-width'] || '1' : '1';
    ctx.stroke();
    return ctx.canvas;
}

function reRender(path, ctx, width, height) {
    clearCanvas(ctx, width, height);
    for (const d of _data) {
        renderCanvas(d, path, ctx, true);
    }
}

export async function testProj1(dom) {
    const width = 960;
    const height = Math.min(width, 720);
    const dpr = window.devicePixelRatio ?? 1;
    const canvas = d3.select(dom).append('canvas')
        .attr("width", dpr * width)
        .attr("height", dpr * height)
        .style("width", `${width}px`)
        .style('background-color', '#c3e8f6')
        .style('display', 'block').style('margin', 'auto');
    let [xc, yc] = projTools.getXyCenter(canvas.node());
    const proj = d3.geoOrthographic().fitExtent([[10, 10], [width - 10, height - 10]], {type: "Sphere"})
        .reflectX(false)
        .reflectY(false)
        .center([0, 0]) // 地理中心点
        .scale(300) // 缩放比例
        .translate([xc, yc])
        .rotate([0, 0, 0]);
    console.log(proj.center(), proj.translate(), proj.rotate());
    const context = canvas.node().getContext('2d');
    context.scale(dpr, dpr);
    // const path = d3.geoPath(proj);
    const path = d3.geoPath(proj, context);

    clearCanvas(context, width, height);

    let bg = {
        type: 'Sphere',
        props: {
            fill: '#87ceeb',
            stroke: 'gray',
            'stroke-width': 0.5
        }
    }

    renderCanvas(bg, path, context);

    renderCanvas(d3.geoGraticule(), path, context);

    const center = {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [0, 0],
        },
        "properties": {
            "name": "Points",
            "fill": 'red'
        }
    }

    const holeData = {
        "type": "Feature",
        "geometry": {
            "type": "Polygon",
            "coordinates": [
                [
                    [0, 0],
                    [0, 10],
                    [10, 10],
                    [10, 0],
                    [0, 0]
                ],
                [
                    [5, 5],
                    [5, 3],
                    [7, 3],
                    [7, 5],
                    [5, 5]
                ]
            ]
        },
        "properties": {
            "name": "Hole Polygon",
            "fill": 'yellow'
        }
    };

    const pointsData = {
        "type": "Feature",
        "geometry": {
            "type": "MultiPoint",
            "coordinates": [
                [0, 85],
                [30, 75],
                [60, 60],
                [90, 45],
                [120, 30],
                [150, 15],
                [180, 0],
                [210, -15],
                [240, -30],
                [270, -45],
                [300, -60],
                [330, -75],
                [360, -85],
            ]
        },
        "properties": {
            "name": "Points",
            "fill": "green"
        }
    }


    // canvas.append('g').append('path')
    //     .datum(d3.geoGraticule())
    //     .attr("d", path)
    //     .attr('stroke', 'grey')
    //     .attr('stroke-width', 1.5)
    //     .attr('stroke-opacity', 0.5)
    //     .attr('fill', 'lightblue')


    // const worldData = await d3.json("https://fastly.jsdelivr.net/npm/world-atlas@2.0.2/countries-110m.json");
    // // 将 TopoJSON 对象转换为 GeoJSON 对象
    // console.log(worldData);
    // const countries = topojson.feature(worldData, worldData.objects.countries);
    // console.log(countries);

    const chData = await d3.json("https://geojson.cn/api/data/100000.json");
    // 将 TopoJSON 对象转换为 GeoJSON 对象
    console.log(chData);
    const provinces = chData.features;
    console.log(provinces);

    // 使用路径生成器绘制国家
    // canvas.append('g').selectAll("path")
    //     .data(countries.features)
    //     .enter().append("path")
    //     .attr("d", path)
    //     .attr("fill", "lightgray")
    //     .attr("stroke", "white");

    // canvas.append('g').append("path")
    //     .datum(holeData)
    //     .attr("class", "polygon")
    //     .attr("d", path)
    //     .attr('fill', 'red');

    // canvas.append('g').selectAll('path')
    //     .data([holeData]).enter().append("path")
    //     .attr("class", "polygon")
    //     .attr("d", path)
    //     .attr('fill', 'red');

    // for (const d of countries.features) {
    //     d.props = {
    //         'fill': 'lightgray'
    //     }
    //     renderCanvas(d, path, context);
    // }

    renderCanvas(holeData, path, context);

    // canvas.append('g').selectAll('path')
    //     .data([pointsData]).enter().append("path")
    //     .attr("class", "points")
    //     .attr("d", path)
    //     .attr('fill', 'blue');
    //
    // canvas.append('g').selectAll('path')
    //     .data([center]).enter().append("path")
    //     .attr("class", "point")
    //     .attr("d", path)
    //     .attr('fill', 'red');

    renderCanvas(pointsData, path, context);

    renderCanvas(center, path, context);


    // proj.translate([240, 125]);
    // console.log(proj.center(), proj.translate(), proj.rotate());
    // canvas.selectAll('path').attr('d', path);

    let drag = d3.drag()
        .on('drag', function (e) {
            console.log('dragged', e);
            let cr = proj.rotate();
            let ratio = 5;
            proj.rotate([cr[0] + e.dx / ratio, cr[1] - e.dy / ratio, cr[2]])
            reRender(path, context, width, height);
        })
    canvas.call(drag);

}